package com.maker.core;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.*;
import com.alipay.api.domain.AlipayDataDataserviceBillDownloadurlQueryModel;
import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
import com.maker.config.AlipayProperties;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;


@Slf4j
public class AlipayTemplate {

    private AlipayProperties alipayProperties;
    private AlipayConfig alipayConfig;

    public AlipayTemplate(AlipayProperties alipayProperties, AlipayConfig alipayConfig) {
        this.alipayProperties = alipayProperties;
        this.alipayConfig = alipayConfig;
    }

    public  String  createOrder(Integer total,String title,String outTradeNo)  {
        try {
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);

            // 构造请求参数以调用接口
            AlipayTradePagePayRequest requestv2 = new AlipayTradePagePayRequest();
            requestv2.setNotifyUrl(alipayProperties.getNotifyUrl());
            requestv2.setReturnUrl(alipayProperties.getReturnUrl());
            BigDecimal total_amount = new BigDecimal(total.toString()).divide(new BigDecimal("100"));
            AlipayTradePagePayModel model = new AlipayTradePagePayModel();
            model.setOutTradeNo(outTradeNo);
            model.setTotalAmount(total_amount.toString());
            model.setSubject(title);
            model.setProductCode("FAST_INSTANT_TRADE_PAY");
            requestv2.setBizModel(model);
            AlipayTradePagePayResponse response = alipayClient.pageExecute(requestv2, "POST");
            if(response.isSuccess()){
                log.info("调用成功,返回结果："+response.getBody());
                return response.getBody();
            }else {
                log.info("调用失败,返回码："+response.getCode()+",返回描述："+response.getMsg());
                throw new RuntimeException("调用支付失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("调用支付失败");
        }
    }

    public  void  closeOrder(String outTradeNo)  {
        log.info("关单接口调用，单号：{}",outTradeNo);
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
            JSONObject  bizContent = new JSONObject();
            bizContent.put("out_trade_no",outTradeNo);
            request.setBizContent(bizContent.toString());
            AlipayTradeCloseResponse  response = alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("关单接口调用成功,返回结果："+response.getBody());
            }else {
                log.info("关单接口调用失败,返回码："+response.getCode()+",返回描述："+response.getMsg());
//                throw new RuntimeException("关单接口失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("关单接口失败");
        }

    }

    public  String  queryOrder(String outTradeNo)  {
        log.info("查询订单接口调用，单号：{}",outTradeNo);
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
            JSONObject  bizContent = new JSONObject();
            bizContent.put("out_trade_no",outTradeNo);
            request.setBizContent(bizContent.toString());
            AlipayTradeCloseResponse  response = alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("查询订单接口调用成功,返回结果："+response.getBody());
                return response.getBody();
            }else {
                log.info("查询订单接口调用失败,返回码："+response.getCode()+",返回描述："+response.getMsg());
//                throw new RuntimeException("查询订单接口失败");
                return null; //该订单不存在
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("查询订单接口失败");
        }

    }


    public  String  refunds(String outTradeNo,Integer total,String reason)  {
        log.info("退款订单接口调用，单号：{}",outTradeNo);
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();
            BigDecimal total_amount = new BigDecimal(total.toString()).divide(new BigDecimal("100"));
            model.setOutTradeNo(outTradeNo);
            model.setRefundReason(reason);
            model.setRefundAmount(total_amount.toString());
            request.setBizModel(model);
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("退款接口调用成功,返回结果："+response.getBody());
                return response.getBody();
            }else {
                log.info("退款失败,返回码："+response.getCode()+",返回描述："+response.getMsg());
//                throw new RuntimeException("退款失败");
                return null; //该订单不存在
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("退款接口失败");
        }

    }


    public  String  queryRefunds(String outTradeNo)  {
        log.info("查询退款接口调用，单号：{}",outTradeNo);
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
            AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
            model.setOutTradeNo(outTradeNo);
            //本测试一个订单对应1个退款单；
            model.setOutRequestNo(outTradeNo);
            request.setBizModel(model);
            AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("查询退款接口调用成功,返回结果："+response.getBody());
                return response.getBody();
            }else {
                log.info("查询退款接口调用失败,返回码："+response.getCode()+",返回描述："+response.getMsg());
//                throw new RuntimeException("查询订单接口失败");
                return null; //该退单单不存在
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("查询退款接口失败");
        }

    }

    public  String  queryBill(String date,String type)  {
        log.info("查询对账单下载地址");
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
            AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
            model.setBillType(type);
            model.setBillDate(date);
            request.setBizModel(model);
            AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("查询退款接口调用成功,返回结果："+response.getBody());
                //获取账单地址
                Gson gson = new Gson();
                HashMap<String, LinkedTreeMap> resultMap = gson.fromJson(response.getBody(), HashMap.class);
                LinkedTreeMap query_response = resultMap.get("alipay_data_dataservice_bill_downloadurl_query_response");
                String bill_download_url = (String)query_response.get("bill_download_url");
                return bill_download_url;
            }else {
                log.info("获取账单url信息失败,返回码："+response.getCode()+",返回描述："+response.getMsg());
//                throw new RuntimeException("查询订单接口失败");
                return null; //该不存在
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("获取账单url信息失败");
        }

    }




    //异步通知验签
    public Boolean rsaCheckV1(Map<String,String> params){
        //调用SDK验证签名
        try {
            Boolean flag = AlipaySignature.rsaCheckV1(params,
                    alipayProperties.getAlipayPublicKey(),
                    AlipayConstants.CHARSET_UTF8,
                    AlipayConstants.SIGN_TYPE_RSA2);
            return flag;
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("异步通知验签异常");
        }

    }


}
